<template>
    <div class="page-container">
        <div class="upload-container">
            <h2>filter</h2>
            <input type="file" accept=".txt" @change="handleFileChange" class="file-input"/>
            <br>
            <LoadingButton
                :loading="isProcessing"
                :disabled="parsedDataCount === 0 || isProcessing"
                @click="uploadData"
            >
                上传数据
            </LoadingButton>
            <StatusMessage
                v-if="parsedDataCount > 0"
                type="info"
                :message="`读取到: ${parsedDataCount} 条数据 (大小: ${fileSize} MB)`"
            />
            <StatusMessage
                v-if="responseHandled"
                :type="remainingLinks.length > 0 ? 'success' : 'error'"
                :message="remainingLinks.length > 0
                    ? `服务器去重剩余: ${remainingLinks.length} 条数据`
                    : '🚨 无剩余数据，所有数据均重复！🚨'"
            >
                <button
                    v-if="remainingLinks.length > 0"
                    @click="downloadLinksAndReset"
                    class="download-button"
                >
                    下载数据
                </button>
            </StatusMessage>
            <StatusMessage
                v-if="duplicateLinks.length > 0"
                type="error"
                :message="`文件中有: ${duplicateLinks.length} 条重复`"
            >
                <ul class="duplicate-list">
                    <li v-for="(link, index) in duplicateLinks" :key="index">{{ link }}</li>
                </ul>
            </StatusMessage>
        </div>
    </div>
</template>
<script setup lang="ts">
import {ref, onMounted} from "vue";
import axios from "axios";
import LoadingButton from "../components/LoadingButton.vue";
import StatusMessage from "../components/StatusMessage.vue";

// 定义数据类型
interface DataItem {
    link: string; // 每个数据项包含一个链接字符串
}

// 定义变量
const file = ref<File | null>(null); // 存储用户选择的文件
const parsedData = ref<DataItem[]>([]); // 存储解析后的数据项
const parsedDataCount = ref(0); // 解析的数据项数量
const fileSize = ref<number>(0); // 文件大小（MB）
const duplicateLinks = ref<string[]>([]); // 存储重复的链接
const remainingLinks = ref<string[]>([]); // 存储上传后剩余的链接
const isProcessing = ref(false); // 控制上传按钮的加载状态
const responseHandled = ref(false); // 标记上传请求是否已完成
let uploadInProgress = false; // 防止重复上传的标记变量

// 设置页面加载后的行为
onMounted(() => {
    document.title = "文本文件上传"; // 当页面加载时，设置文档标题
});

// 文件更改事件处理
const handleFileChange = async (event: Event) => {
    const target = event.target as HTMLInputElement;
    if (target.files && target.files.length > 0) {
        const selectedFile = target.files[0];
        // 检查文件大小是否超过 10MB
        if (selectedFile.size > 10 * 1024 * 1024) {
            alert("文件太大，请选择小于10MB的文件");
            return;
        }
        // 检查文件类型是否为文本文件
        if (selectedFile.type !== "text/plain") {
            alert("请上传文本文件（.txt）");
            return;
        }
        file.value = selectedFile;
        // 计算并保存文件大小，以 MB 为单位
        fileSize.value = Number((file.value.size / (1024 * 1024)).toFixed(2));

        const reader = new FileReader(); // 创建文件读取器对象
        reader.onload = (e) => {
            const data = e.target?.result; // 读取文件内容
            if (data) {
                // 将文件内容按行分割，去除空白行和前后空格
                const rawData: string[] = (data as string).split("\n").map(line => line.trim()).filter(line => line);
                const uniqueLinks = new Set<string>(); // 用于存储唯一链接
                const filteredData: DataItem[] = []; // 用于存储去重后的数据项
                duplicateLinks.value = []; // 重置重复链接数组

                // 遍历每一行数据，检查是否为链接且是否重复
                rawData.forEach((link) => {
                    // 如果不是有效的链接则跳过
                    if (uniqueLinks.has(link)) {
                        duplicateLinks.value.push(link); // 如果链接重复，将其添加到重复链接列表
                    } else {
                        uniqueLinks.add(link); // 否则，将链接添加到唯一集合
                        filteredData.push({link}); // 并添加到过滤后的数据列表
                    }
                });

                parsedData.value = filteredData; // 将去重后的数据存储到变量中
                parsedDataCount.value = parsedData.value.length; // 更新数据项数量
            }
        };
        reader.readAsText(file.value); // 以文本格式读取文件内容
    }
};

// 上传数据
const uploadData = async () => {
    if (uploadInProgress) {
        return; // 如果上传已经在进行中，则返回，防止重复请求
    }
    uploadInProgress = true;
    isProcessing.value = true; // 设置处理状态为 true，表示正在处理
    try {
        // 向服务器发送 POST 请求，上传解析后的数据
        const result = await axios.post<{
            remainingCount: string[];
        }>("/api/upload-data", parsedData.value, {
            headers: {
                'Content-Type': 'application/json',
            },
        });
        remainingLinks.value = result.data.remainingCount; // 保存服务器返回的剩余数据
        responseHandled.value = true; // 设置响应已处理标志为 true
    } catch (error) {
        // 如果发生错误，进行错误处理
        if (axios.isAxiosError(error)) {
            alert(`上传失败: ${error.response?.status} - ${error.response?.data.message}`); // 显示具体错误信息
        } else {
            alert('发生未知错误，请稍后重试。'); // 显示未知错误信息
        }
    } finally {
        isProcessing.value = false; // 无论是否成功，处理结束后重置处理状态
        uploadInProgress = false; // 上传结束，重置上传进行标志
    }
};

// 下载剩余链接并重置
const downloadLinksAndReset = () => {
    // 创建一个 Blob 对象，用于存储剩余链接的文本内容
    const blob = new Blob([remainingLinks.value.join("\n")], {type: "text/plain"});
    const link = document.createElement("a"); // 创建一个链接元素
    link.href = URL.createObjectURL(blob); // 将 Blob 转换为可下载的链接
    link.download = "去重后的链接.txt"; // 设置下载文件的名称
    document.body.appendChild(link); // 将链接元素添加到文档中
    link.click(); // 模拟点击事件，触发下载
    document.body.removeChild(link); // 下载完成后移除链接元素

    // 重置所有变量
    file.value = null;
    parsedData.value = [];
    parsedDataCount.value = 0;
    fileSize.value = 0;
    remainingLinks.value = [];
    duplicateLinks.value = [];
    responseHandled.value = false;
    isProcessing.value = false;
    uploadInProgress = false;
};
</script>

<style scoped>
/* 外层容器左右居中对齐 */
.page-container {
    max-width: 800px; /* 限制内容宽度 */
    margin: 0 auto; /* 左右居中 */
    padding: 20px;
}

/* 指南样式，居中对齐内容 */
.instructions {
    margin-bottom: 20px;
    background: #ffffff;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    text-align: center; /* 水平居中内容 */
}

/* 上传容器，居中对齐内容 */
.upload-container {
    background: #ffffff;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    text-align: center; /* 水平居中内容 */
}

/* 文件选择按钮 */
.file-input {
    margin: 10px 0 20px;
    padding: 10px;
    border: 2px solid #4caf50;
    border-radius: 8px;
    cursor: pointer;
}

/* 状态消息框，内容居中 */
.status-message {
    padding: 15px;
    border-radius: 8px;
    margin: 10px 0;
    text-align: center; /* 水平居中内容 */
}

/* 去重数据列表，区域居中且内容居中 */
.duplicate-list {
    max-height: 200px;
    overflow-y: auto; /* 启用滚动 */
    margin-top: 10px;
    padding: 10px;
    background: #fdecea;
    border-radius: 8px;
    border: 1px solid #f5c6cb;
    color: #a94442;
    list-style: none; /* 去掉默认列表样式 */
    text-align: center; /* 水平居中内容 */
    display: flex;
    flex-direction: column;
    align-items: center; /* 子元素居中对齐 */
}

/* 列表项样式 */
.duplicate-list li {
    margin-bottom: 5px;
    word-break: break-word; /* 长链接换行 */
}

/* 下载按钮 */
.download-button {
    margin-top: 20px;
    padding: 10px 20px;
    background: #007bff;
    color: white;
    border: none;
    border-radius: 8px;
    cursor: pointer;
    display: inline-block;
}

.download-button:hover {
    background: #0056b3;
}

/* 通用按钮 */
button {
    display: inline-block;
    text-align: center;
    cursor: pointer;
    border-radius: 8px;
    padding: 10px 20px;
    transition: background 0.3s;
}
</style>
